/**
 * 给定2个字符串S和T，要求满足以下条件：
 * 1. S取前缀记作ps, T取后缀记作st, 要求 ps == st, 且均为回文串
 * 2. S取后缀ss, T取前缀pt, 要求 ss == pt，且均为回文串
 * 3. ps和ss非空且不能重叠
 * 4. pt和st非空且不能重叠
 * 5. 要求4个串加起来最长
 * 
 * 对S和T的每一个前缀和后缀，分别计算正反哈希
 * 正反哈希相等说明就是一个回文串
 * 
 * S长度记作N，T长度记作M
 * 弄一个动态数组pre
 * for i, j in zip([0, N-1],[M-1, 0]):
 *     if Si != Tj: continue
 *     if S[0...i]和T[M-j...M-1] 是回文串: pre.push_back(i) 
 * 弄一个动态数组suf
 * for i, j in zip([N-1, 0], [0, M-1]):
 *     if Si != Tj: continue
 *     if S[N-i...N-1]和T[0..j] 均是回文串: suf.push_back(i)
 * 
 * 把suf数组reverse一下，然后对pre中的每个i，找到最小的符合条件的j，计算一下求最大值即可
 * 可以使用二分搜索
 * 令 limit = min(N, M)
 * for i in pre:
 *     target = N + i + 1 - limit
 *     在suf数组中找到满足 >= target 的最小的数，记作j
 *     ans = max(ans, i + 1 + N - j)
 * ans + ans 是答案
 */
#include <bits/stdc++.h>
using namespace std;

using llt = long long;
using vi = vector<int>;

struct Tuple{ // 用于计算双哈希
    enum {SZ = 2};
    array<size_t, SZ> val;

    Tuple():val({0, 0}){}
    Tuple(size_t a):val({a, a}){}
    Tuple(size_t a, size_t b):val({a, b}){}
    // Tuple(size_t a, size_t b, size_t c):val({a, b, c}){}

    Tuple & operator *= (const Tuple & rhs){
        for(int i=0;i<SZ;++i){
            val[i] *= rhs.val[i];
        }
        return *this;
    }

    Tuple & operator += (const Tuple & rhs){
        for(int i=0;i<SZ;++i){
            val[i] += rhs.val[i];
        }
        return *this;
    }

    static const Tuple & one() {
        static const Tuple ONE(1);
        return ONE;
    }

    static const Tuple & seed(){
        /// 第一个用10方便调试
        static const Tuple SEED(10, 13331);
        return SEED;
    }
};

const Tuple operator + (const Tuple & a, const Tuple & b){
    Tuple tmp(a); return tmp += b;
}

const Tuple operator * (const Tuple & a, const Tuple & b){
    Tuple tmp(a); return tmp *= b;
}

bool operator == (const Tuple & a, const Tuple & b){
    for(int i=0;i<Tuple::SZ;++i)if(a.val[i]!=b.val[i])return false;
    return true;
}

bool operator != (const Tuple & a, const Tuple & b){
    return ! (a == b);
}

ostream & operator << (ostream & os, const Tuple & t){
    os << "{" << t.val[0];
    for(int i=1;i<Tuple::SZ;++i){
        os << " ," << t.val[i];
    }
    return os << "}";
}


int N, M;
string S, T;
vector<Tuple> Pow;

void init(int n){
    Pow.clear(); Pow.reserve(n);
    Pow.push_back(Tuple::one());
    for(int i=1;i<n;++i){
        Pow.push_back(Pow.back() * Tuple::seed());
        
    }
    return;
}

void calcff(const vi & s, vector<pair<Tuple, Tuple>> & vec){
    int n = s.size();
    vec.assign(n, {});
    vec[0].first = vec[0].second = Tuple(s[0]);
    for(int i=1;i<n;++i){
        vec[i].first = vec[i - 1].first * Tuple::seed() + Tuple(s[i]);
        vec[i].second = vec[i - 1].second + Tuple(s[i]) * Pow[i];
    }
    return;
}

void calcbb(const vi & s, vector<pair<Tuple, Tuple>> & vec){
    int n = s.size();
    vec.assign(n, {});
    vec[n - 1].first = vec[n - 1].second = Tuple(s[n - 1]);
    for(int i=n - 2;i>=0;--i){
        vec[i].first = vec[i + 1].first * Tuple::seed() + Tuple(s[i]);
        vec[i].second = vec[i + 1].second + Tuple(s[i]) * Pow[n - 1 - i];
    }
    return;
}

bool check(
    const string & s, int sp, const vector<pair<Tuple, Tuple>> & svec,
    const string & t, int tp, const vector<pair<Tuple, Tuple>> & tvec
){
    if(svec[sp].first != svec[sp].second) return false;
    if(tvec[tp].first != tvec[tp].second) return false;
    if(svec[sp].first != tvec[tp].first) return false;
    return true;
}


int proc(){
    init(max(N, M));
    
    vi s(N, 0);
    for(int i=0;i<N;++i) s[i] = S[i] - 'a' + 1;

    vi t(M, 0);
    for(int i=0;i<M;++i) t[i] = T[i] - 'a' + 1;


    vector<pair<Tuple, Tuple>> ffs, fft;
    calcff(s, ffs);
    calcff(t, fft);

    vector<pair<Tuple, Tuple>> bbs, bbt;
    calcbb(s, bbs);
    calcbb(t, bbt);

    vector<int> pre;
    for(int i=0,j=M-1;i<N&&j>=0;++i,--j){
        if(S[i] != T[j]) break;
        if(check(S, i, ffs, T, j, bbt)){
            pre.emplace_back(i);
        }
    }

    if(pre.empty()) return -1;

    vector<int> suf;
    for(int j=0,i=N-1;i>=0&&j<M;++j,--i){
        if(S[i] != T[j]) break;
        if(check(T, j, fft, S, i, bbs)){
            suf.push_back(i);
        }
    }

    if(suf.empty()) return -1;
    reverse(suf.begin(), suf.end());

    int limit = min(N, M);
    int ans = -1;
    for(auto i : pre){
        auto pp = equal_range(suf.begin(), suf.end(), N + i + 1 - limit);
        if(pp.first != pp.second){
            auto t = *pp.first;
            int tmp = i + 1 + N - t;
            if(-1 == ans or ans < tmp){
                ans = tmp;
            }
        }else if(pp.second != suf.end()){
            auto t = *pp.second;
            int tmp = i + 1 + N - t;
            if(-1 == ans or ans < tmp){
                ans = tmp;
            }
        }
    }
    return ans + ans;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    int nofkase = 1; 
    // cin >> nofkase;
    while(nofkase--){
        cin >> N >> M >> S >> T;
        cout << proc() << "\n";
    }
    return 0;
}